<template>
	<div
		:class="classes()"
		:style="style"
	>
		<div
			ref="referenceRef"
			:class="refClass"
			:style="refStyle"
			v-on="referenceListenersFn()"
		><slot v-bind="slotScope()"/></div>
		<Floating
			v-if="floatingExist"
			ref="floatingRef"
			v-slot="data"
			v-bind="$attrs"
			:reference-ref="referenceRef"
			:visible="visible()"
			:hide-on-click="hideOnClick"
			:appear="appearFn()"
			@mouseenter="mouseenterFn"
			@mouseleave="mouseleaveFn"
			@hidden="hiddenFn"
			@hide-click="hide"
		><slot
			name="content"
			v-bind="data"
			:show="show"
			:hide="hide"
			:toggle="toggle"
		/></Floating>
	</div>
</template>

<script setup lang="ts">
import type {
	PoptipTriggerType,
} from './type';
import type {
	LimitProcessor,
} from '../Floating/type';
import Floating from '../Floating/Floating.vue';
import usePoptip from '../../../composables/usePoptip';
/**
 * 气泡提示组件
 * @author 唐国雄
 * @date 2022/9/22
 * 属性----------------------
 * v-model				手动控制是否显示
 * :trigger				触发方式
 * :hide-on-click		点击隐藏
 * :content				提示内容
 * :placement			提示位置
 * :max-width			使用content时的最大宽度
 * :arrow				是否显示箭头
 * :shift				是否自动偏移
 * :offset				偏移
 * :padding				边距
 * :arrow-padding		箭头偏移边距
 * :interactive			可交互
 * :interactive-border	可交互的外延
 * :disabled			禁用状态
 * :append-to			dom插入位置
 * :theme				主题class
 * :appear				初始渲染动画
 * :animation			动画
 * :ref-class			参考元素类名
 * :ref-style			参考元素样式
 * 事件----------------------
 * @update:modelValue	显示状态趋势(实际状态不一定, 跟disabled和value相关)
 * @show				开始显示
 * @shown				显示动画完毕
 * @hide				开始隐藏
 * @hidden				隐藏动画完毕
 * @hide-click			点击隐藏
 * 插槽----------------------
 * #default				参考元素
 * #content				提示内容
 * 方法----------------------
 * show()				显示
 * hide()				隐藏
 * toggle(show)			切换显示状态
 * computePoptip()		重新计算样式
 */
const emit=defineEmits<{
	(e:'update:modelValue',val:boolean):void;
	(e:'show'):void;
	(e:'hide'):void;
}>();
const props=withDefaults(defineProps<{
	class?:any;
	style?:any;
	modelValue?:boolean|null;
	trigger?:PoptipTriggerType|null;
	hideOnClick?:boolean|'toggle';
	interactive?:boolean;
	disabled?:boolean;
	appear?:boolean;
	refClass?:any;
	refStyle?:any;
}>(),{
	modelValue:null,
	trigger:'hover',
	hideOnClick:true,
});
//region 气泡提示控制逻辑
const {
	referenceRef,
	floatingRef,
	visible,
	appearFn,
	floatingExist,
	referenceListenersFn,
	mouseenterFn,
	mouseleaveFn,
	hiddenFn,
	show,
	hide,
	toggle,
}=usePoptip({
	emitInput(val){
		emit('update:modelValue',val);
	},
	emitShow(){
		emit('show');
	},
	emitHide(){
		emit('hide');
	},
	showStatus(){
		return props.modelValue;
	},
	trigger(){
		return props.trigger;
	},
	hideOnClick(){
		return props.hideOnClick;
	},
	interactive(){
		return props.interactive;
	},
	disabled(){
		return props.disabled;
	},
	appear(){
		return props.appear;
	},
});
//endregion
//region 类名
const classes=() => {
	return 'pf-Poptip'+
		(props.class?' '+props.class:'');
};
//endregion
//region 插槽作用域
const slotScope=(() => {
	return {
		visible:visible(),
		show,
		hide,
		toggle,
		computePoptip,
	};
});
//endregion
//region 重新计算样式
function computePoptip(limitFn?:LimitProcessor):Promise<boolean>{
	const floatingRefVal=floatingRef.value;
	if(floatingRefVal){
		return floatingRefVal.computePoptip(limitFn);
	}
	return Promise.resolve(false);
}
//endregion
//region 导出的内容
defineExpose({
	show,
	hide,
	toggle,
	computePoptip,
});
//endregion
</script>

<script lang="ts">
export default {
	inheritAttrs:false,
};
</script>